import os, yaml
from reportlab.platypus import *
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
from  reportlab.lib.styles import ParagraphStyle as PS

PAGE_HEIGHT=defaultPageSize[1]
styles = getSampleStyleSheet()


import yaml, os, sys
sys.path.append("gmultiserver")
from utils import config

file_name = './gmultiserver/config.yaml'
config.readConfig(file_name, True)
stream = file(file_name, 'r')
cfg = yaml.load(stream)
if cfg is None:
	print 'Wrong config.yaml'
	exit(1)

Title = "GMultiServer Manual ver %s" % config.get_pkg('version')

Author = config.get_pkg('author')

URL = "http://code.google.com/p/gmultiserver/"

email = "first name dot last name @gmail.com"

Abstract = """This paper describes the using of GMultiServer. How to write and customize YAML
files used as configuration input. Please note that GMultiServer is in development phase."""


from  reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from  reportlab.platypus.tableofcontents import TableOfContents
from  reportlab.platypus.frames import Frame
from  reportlab.lib.units import cm

h1 = PS(name = 'Heading1',
    fontSize = 14,
    leading = 16)

h2 = PS(name = 'Heading2',
    fontSize = 12,
    leading = 14)

from reportlab.lib.units import inch
pageinfo = Title

def myFirstPage(canvas, doc):
	# trick for add vector graphics by opensource reportlab pdf
	canvas.saveState()
	from pdfrw import PdfReader
	from pdfrw.buildxobj import pagexobj
	from pdfrw.toreportlab import makerl
	page = PdfReader('doc/gmultiserver1.pdf').pages[0]
	page_template = pagexobj(page)
	rl_obj = makerl(canvas, page_template)
	canvas.doForm(rl_obj)
	canvas.restoreState()
	canvas.saveState()

	canvas.setFont('Times-Bold',16)
	canvas.drawString(108, PAGE_HEIGHT-108, Title)
	canvas.setFont('Times-Roman',9)
	canvas.drawString(inch, 0.75 * inch, "First Page / %s" % pageinfo)
	canvas.restoreState()
	canvas.setAuthor(config.get_pkg('author'))
	canvas.setCreator(config.get_pkg('author'))
	canvas.setTitle(Title)
	canvas.setSubject('GMultiServer Manual')
	canvas.setKeywords(config.get_pkg('keywords'))
	

def myLaterPages(canvas, doc):
	#canvas.drawImage("snkanim.gif", 36, 36)
	canvas.saveState()
	#canvas.setStrokeColorRGB(1,0,0)
	#canvas.setLineWidth(5)
	#canvas.line(66,72,66,PAGE_HEIGHT-72)
	canvas.setFont('Times-Roman',9)
	canvas.drawString(inch, 0.75 * inch, "Page %d %s" % (doc.page, pageinfo))
	canvas.restoreState()

class MyDocTemplate(BaseDocTemplate):
	def __init__(self, filename, **kw):
		self.allowSplitting = 0
		apply(BaseDocTemplate.__init__, (self, filename), kw)
		#template = PageTemplate('normal', [])
		#self.addPageTemplates(template)
		frameT = Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')
		self.addPageTemplates([PageTemplate(id='First', frames=frameT, onPage=myFirstPage),
                                       PageTemplate(id='Later', frames=frameT, onPage=myLaterPages)])

	def afterFlowable(self, flowable):
		"Registers TOC entries."
		if flowable.__class__.__name__ == 'Paragraph':
			text = flowable.getPlainText()
			style = flowable.style.name
			if style == 'Heading1':
				level = 0
			elif style == 'Heading2':
				level = 1
			else:
				return
			E = [level, text, self.page]
			#if we have a bookmark name append that to our notify data
			bn = getattr(flowable,'_bookmarkName',None)
			if bn is not None: E.append(bn)
			self.notify('TOCEntry', tuple(E))


def go():
	Elements.insert(0, Spacer(0, inch))
	#doc = SimpleDocTemplate('doc/gmultiserver_manual_v%s.pdf' % config.get_pkg('version'))
	doc = MyDocTemplate('doc/gmultiserver_manual_v%s.pdf' % config.get_pkg('version'))
	doc.multiBuild(Elements) #, onFirstPage=myFirstPage, onLaterPages=myLaterPages)
	from shutil import copyfile
	copyfile('doc/gmultiserver_manual_v%s.pdf' % config.get_pkg('version'), '/tmp/gmultiserver_manual_latest.pdf')

Elements = []

def doHeading(text, sty):
    from hashlib import sha1
    #create bookmarkname
    bn=sha1(text+sty.name).hexdigest()
    #modify paragraph text to include an anchor point with name bn
    h=Paragraph(text+'<a name="%s"/>' % bn,sty)
    #store the bookmark name on the flowable so afterFlowable can see this
    h._bookmarkName = bn
    Elements.append(h)

HeaderStyle = styles["Heading1"]
HeaderStyle2 = styles["Heading2"]
HeaderStyle3 = styles["Heading3"]
NStyle = styles["Definition"]

def header(txt, style=HeaderStyle, klass=Paragraph, sep=0.3):
        from hashlib import sha1
        bn = sha1(txt+style.name).hexdigest()
	s = Spacer(0.2*inch, sep*inch)
	Elements.append(s)
	h = Paragraph(txt + '<a name="%s"/>' % bn, style)
	h._bookmarkName = bn
	Elements.append(h)

def par(txt, style=HeaderStyle, klass=Paragraph, sep=0.3):
	s = Spacer(0.2*inch, sep*inch)
	Elements.append(s)
	para = klass(txt, style)
	Elements.append(para)

ParaStyle = styles["Normal"]

def p(txt):
	return par(txt, style=ParaStyle, sep=0.1)

def p2(txt):
	return header(txt, style=HeaderStyle2, sep=0.3)

def p3(txt):
	return par(txt, style=HeaderStyle3, sep=0.1)

def p4(t1, txt):
	return par('<i>%s</i> - %s' % (t1, txt), style=ParaStyle, sep=0.1)

PreStyle = styles["Code"]

def pre(txt):
	s = Spacer(0.1 * inch, 0.1 * inch)
	Elements.append(s)
	p = Preformatted(txt, PreStyle)
	Elements.append(p)

#header(Title, sep=0.1. style=ParaStyle)
header(Author, sep=0.1, style=ParaStyle)
header(URL, sep=0.1, style=ParaStyle)
header(email, sep=0.1, style=ParaStyle)
header("ABSTRACT")
p(Abstract)
#Elements.append(Image('doc/gmultiserver1.png',6*inch, 5*inch ))
Elements.append(NextPageTemplate('Later'))
Elements.append(PageBreak())
toc = TableOfContents()
from  reportlab.lib.styles import ParagraphStyle as PS
toc.levelStyles = [
    PS(fontName='Times-Bold', fontSize=20, name='TOCHeading1', leftIndent=20, firstLineIndent=-20, spaceBefore=10, leading=16),
    PS(fontSize=18, name='TOCHeading2', leftIndent=40, firstLineIndent=-20, spaceBefore=5, leading=12),
]
toc.addEntry(1, 'bla', 1)
Elements.append(toc)

Elements.append(PageBreak())

header('Config files')
p('Config files are YAML files with the Jinja2 support in the same time. This allows to use power of YAML files with all benefits brings by Jinja2 templates.  For example YAML does not have mechanism of import other files by it\'s possible but call Jinja2 "include" command.')
p('Example:')
pre('{% include "examples/generic.wav.yaml" %}')
p('GMultiServer has also some build-in Jinja valiables like interface name + "_ip" contain ip addresses or gmultiserver_version contains version number (e.g. {{ eth4_ip }} ). Probably list of build-in variables will grow and of course it\'s also possible to extend this list by own variables declared as Jinja2 command "set" in YAML comments blocks.')

header('How to run/use')
p2('Run as deamon')
p('Example:')
pre('gmultiserver file.yaml start')
pre('gmultiserver file.yaml stop')

p2('Run as standalone tool')
p('Example:')
pre('gmultiserver file.yaml')

p2('Execute command on demand')
p('Example:')
pre('gmultiserver file.yaml name_of_object method_name arg1 ... argn')

p2('Change objects parameters values')
p('Example:')
pre('gmultiserver file.yaml name_of_object.param_name: value')

file_name = os.path.dirname(__file__) + '/../gmultiserver/' + 'config.yaml'
stream = file(file_name, 'r')
c = yaml.load(stream)
a = {}
e = {}

for i in c['classes']:
	if 'doc' in c['classes'][i]:
		cc = config.get_schema(i)
		if cc is None:
			print i
		d = c['classes'][i]['doc']
		if d['type'] not in a:
			a[d['type']] = []
			a[d['type']].append([1, i])
			a[d['type']].append('')
		else:
			a[d['type']].append('')
			a[d['type']].append([1, i])
			a[d['type']].append('')
		t = a[d['type']]
		t.append(d['desc'])
		if cc is not None and 'params' in cc:
			t.append([2, 'Params:'])
			for j in cc['params']:
				df = ''
				if 'def' in cc['params'][j] and cc['params'][j]['def'] != '':
					df = '(def: %s)' % str(cc['params'][j]['def'])
				if 'desc' in cc['params'][j]:
					t.append([3, '%s [%s]' % (j, cc['params'][j]['type']), df + ' ' + cc['params'][j]['desc']])
				else:
					t.append([3, '%s [%s]' % (j, cc['params'][j]['type']), df])
		if cc is not None and 'props' in cc:
			t.append([2, 'Properties:'])
			for j in cc['props']:
				df = ''
				if 'def' in cc['props'][j] and cc['props'][j]['def'] is not None and cc['props'][j]['def'] != '':
					df = '(def: %s)' % str(cc['props'][j]['def'])
				if 'desc' in cc['props'][j]:
					t.append([3, '%s [%s]' % (j, cc['props'][j]['type']), df + ' ' + cc['props'][j]['desc'] ])
				else:
					t.append([3, '%s [%s]' % (j, cc['props'][j]['type']), df])

		if cc is not None and 'methods' in cc:
			t.append([2, 'Methods:'])
			for j in cc['methods']:
				args = ''
				if 'args' in cc['methods'][j]:
					args = ' %s' % repr(cc['methods'][j]['args'])
				if 'desc' in cc['methods'][j]:
					t.append([3, j + args, cc['methods'][j]['desc']])
				else:
					t.append([3, j + args, '(no description)'])

		if 'example' in d:
			f = open('./examples/' + d['example'])
			r = f.read()
			t.append([0, r])
			f.close()


for i in c['doc_order']:
	header(i)
	print i
	for j in a[i]:
		if type(j) is type([]):
			if j[0] == 0:
				p3('Example:')
				pre(j[1])
			elif j[0] == 1:
				p2(j[1])
			elif j[0] == 2:
				p3(j[1])
			elif j[0] == 3:
				p4(j[1], j[2])
		else:
			p(j)

header("References/Links")

p("""[Gevent]: Gevent description and examples,
http://www.gevent.org/""")

p("""[YAML]: YAML description and examples,
http://www.yaml.org/start.html""")

p("""[ZMQ]: ZMQ description and manual,
http://www.zeromq.org/intro:read-the-manual""")

p("""[Jinja]: Jinja2 template language,
http://jinja.pocoo.org/""")

go()
